# Copyright (c) 2013, yuxinyong and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe import _
from zelin_am.utils import *
from frappe.utils import flt
import operator

def execute(filters=None):		
	columns = get_columns(filters.get('item_code'), filters.get('summary_level') )
	data = get_data(filters)
	return columns, data

def get_columns(item_code, summary_level):
	columns = []
	if not item_code:
		columns.extend([
			{
				"label": _("Item Code"),
				"fieldtype": "Link",
				"fieldname": "item_code",
				"options":'Item',			
				"width": 100
			},
			{
				"label": _("Item Name"),				
				"fieldname": "item_name",				
				"width": 150
			}
		])
	if not summary_level:
		columns.extend([
			{
				"label": _("Date"),
				"fieldtype": "Date",
				"fieldname": "due_date",			
				"width": 100
			},
			{
				"label": _("Ref Doctype"),
				"fieldtype": "Link",
				"fieldname": "ref_doctype",
				"options": "DocType",			
				"width": 100
			},
			{
				"label": _("Ref Docname"),
				"fieldtype": "Dynamic Link",
				"fieldname": "ref_docname",
				"options": "ref_doctype",
				"width": 140
			},
			{
				"label": _("Supply/Demand"),
				"fieldtype": "Float",
				"fieldname": "qty",
				"width": 100
			},
			{
				"label": _("Available Qty"),
				"fieldtype": "Float",
				"fieldname": "available_qty",
				"width": 100
			},
			{
				"label": _("Stock UOM"),
				"fieldtype": "Link",
				"fieldname": "stock_uom",
				"options": "UOM",
				"width": 100
			},
			{
				"label": _("Business Partner Type"),
				"fieldtype": "Link",
				"fieldname": "partner_type",
				"options": "DocType",			
				"width": 140
			},
			{
				"label": _("Business Partner"),
				"fieldtype": "Dynamic Link",
				"fieldname": "partner",
				"options": "partner_type",
				"width": 140
			},
			{
				"label": _("Warehouse"),
				"fieldtype": "Link",
				"fieldname": "warehouse",
				"options":"Warehouse",
				#"hidden":1,
				"width": 120
			}		
		])
	else:
		columns.extend([
			{
				"label": _("%s" % summary_level),
				"fieldtype": "Data",
				"fieldname": "period",			
				"width": 120
			},				
			{
				"label": _("Requirements"),
				"fieldtype": "Float",
				"fieldname": "requirement_qty",
				"width": 150
			},
			{
				"label": _("Supply"),
				"fieldtype": "Float",
				"fieldname": "receive_qty",
				"width": 150
			},
			{
				"label": _("Available Qty"),
				"fieldtype": "Float",
				"fieldname": "available_qty",
				"width": 120
			}
		])
	return columns

def get_data(filters):
	def get_period(in_date, summary_level):
		if summary_level == 'Day':
			res = in_date
		elif summary_level == 'Week':
			week_tuple = in_date.isocalendar()
			res = _('W {0}/{1}').format(week_tuple[0],week_tuple[1])
		else:
			res = _('M {0}/{1}').format(in_date.year, in_date.month)
		return res	
		
	company = filters.get('company')
	item_code = filters.get('item_code')
	warehouses = filters.get('warehouse')
	if not warehouses:
		warehouses =  frappe.get_all('Warehouse', filters={'company': company, 'mrp_exclude':0}, pluck='name')	
	summary_level = filters.get('summary_level')
	#数据结构 date, item_code, ref doctype, ref docname, d[3] warehouse
	combine_list = []
	item_code_onhand_map = get_item_code_onhand_map(company)
	fn = (
            (get_open_so,21),
            (get_open_wo_gi,22),
            (get_open_mr_gi,23),
            (get_open_subcontract_gi,24),
            (get_open_wo,11),
        	(get_open_po,12),
            (get_open_mr,13)
		)
	item_code_list = []
	planner = filters.get('planner')
	if item_code:
		item_code_list = [item_code]
	elif planner:
		item_code_list = frappe.get_all('Item Default', filters={'planner': planner,'company':company}, pluck='parent')

	for (f, sort_key) in fn:
		data_list = f(warehouses, item_code_list = item_code_list, sort_key = sort_key)
		combine_list.extend(data_list)
	combine_list.extend(get_open_plan_order(company, item_code_list = item_code_list, sort_key = 14, mrp = filters.get('mrp')))
	combine_list.extend(get_open_plan_order_items(company, item_code_list = item_code_list, sort_key = 25, mrp = filters.get('mrp')))		
	#sort by item_code, date, then sort key (supply:1 or demand:2)
	combine_list = sorted(combine_list, key=lambda k: (k['item_code'], k['due_date'], k['sort_key'],k['ref_docname']))		
	row_cnt = len(combine_list)
	last_item_code, last_due_date, running_availability = None, None, 0
	data = []
	for idx, d in enumerate(combine_list):
		item_code, qty, date_ = (d.item_code, d.qty, d.due_date)
		if item_code != last_item_code:
			open_on_hand,stock_uom = get_item_code_onhand(item_code, item_code_onhand_map)
			open_row = frappe._dict({
				#'due_date': frappe.utils.today(),
				'ref_doctype': _('Initial Stock'),
				'period': _('Initial Stock'),				
				'available_qty': open_on_hand,
				'stock_uom': stock_uom
			})
			data.append(open_row)
			running_availability = open_on_hand
			requirement_qty = receive_qty = 0
			last_item_code = item_code	
		if summary_level:
			period = get_period(date_, summary_level)
			if qty > 0:
				requirement_qty += qty
			else:
				receive_qty += qty
			# addup and output per period change	
			if (idx == row_cnt - 1 or 
					( period != get_period(combine_list[idx+1]['due_date'], summary_level) or 
				  	item_code != combine_list[idx+1]['item_code'])
				):
				running_availability += requirement_qty + receive_qty
				d.period,d.receive_qty,d.requirement_qty,d.available_qty = (
					period, receive_qty,requirement_qty,running_availability)
				data.append(d)
				requirement_qty = receive_qty = 0
		else:
			running_availability += qty
			d['available_qty'] = running_availability			
			data.append(d)
	return data

"""
from zelin_am.agile_manufacturing.report.stock_requirements_list.stock_requirements_list import *
filters =frappe._dict({'company':'frappedemo'})
c, d = execute(filters)
"""